package homework_4_minesweeper;

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

public class GameBoardPanel extends JPanel implements MouseListener {
    private static int row;
    private static int col;
    private static int num;
    private static int numOfUnrevealedCells;
    private static final long serialVersionUID = 1L;
    private Cell[][] cells;

    public GameBoardPanel(){
        this.setLayout(new GridLayout());

    }
    public void newGame(){
        newGame(row,col,num);
    }
    public void newGame(int row,int col,int num){
        removeAll();
        SouthMenu.setMine(num);
        SouthMenu.setTime(0);
        SouthMenu.start();
        MineSweeperMain.setClickable(true);     //进行新游戏，要设置成“格子可以点击”
        GameBoardPanel.row=row;
        GameBoardPanel.col=col;
        GameBoardPanel.num=num;
        GameBoardPanel.numOfUnrevealedCells=row*col;
        this.setLayout(new GridLayout(row,col,2,2));
        cells=new Cell[row][col];
        for (int r = 0; r < row; r++) {
            for (int c = 0; c < col; c++) {
                cells[r][c] = new Cell(r, c);
                this.add(cells[r][c]);
                cells[r][c].addMouseListener(this);
            }
        }
    }

    public void lose(){
        for (Integer i : MineMap.getMineMap()) {
            cells[MinesweeperUtilities.returnToRow(i, col)][MinesweeperUtilities.returnToCol(i, col)].reveal();
            cells[MinesweeperUtilities.returnToRow(i, col)][MinesweeperUtilities.returnToCol(i, col)].setForeground(Color.BLACK);
            cells[MinesweeperUtilities.returnToRow(i, col)][MinesweeperUtilities.returnToCol(i, col)].setIconMine();
        }
        SouthMenu.lose();
        MineSweeperMain.setClickable(false);
    }
    public void win(){
        MineSweeperMain.setClickable(false);
        SouthMenu.win();
    }

    public static int getCol() {
        return col;
    }

    public static int getRow() {
        return row;
    }

    public static int getNum() {
        return num;
    }

    public void reveal(int num){
            int r = MinesweeperUtilities.returnToRow(num, col);
            int c = MinesweeperUtilities.returnToCol(num, col);
            if (MinesweeperUtilities.isValid(r, c, row, col) && (!cells[r][c].getRevealedStatus())) {
                if (MineMap.getMineMap().contains(num)) {
                    lose();
                    return;
                }
                int numOfMines = 0;
                for (int i = r - 1; i <= r + 1; i++) {
                    for (int j = c - 1; j <= c + 1; j++) {
                        if (MinesweeperUtilities.isValid(i, j, row, col) && MineMap.getMineMap().contains(MinesweeperUtilities.codeToNum(i, j, col))) {
                            numOfMines++;
                        }
                    }
                }
                cells[r][c].setNumberOfMinesAround(numOfMines);
                cells[r][c].reveal();
                if (numOfMines == 0) {
                    cells[r][c].setText("");
                    for (int i = r - 1; i <= r + 1; i++) {
                        for (int j = c - 1; j <= c + 1; j++) {
                            if (i != r || j != c) {
                                reveal(i, j);
                            }
                        }
                    }
                } else {
                    cells[r][c].setText("" + numOfMines);
                    cells[r][c].setColor(numOfMines);
                }
            }
            if(numOfUnrevealedCells==MineMap.getMineMap().size()){
                win();
                return;
            }
    }
    public void reveal(int row,int col){        //重载，先检查坐标是否合理，再编码成供MineMap和reveal(int num)识别的编号。否则会出现不合理坐标编码成正常号码然后再反解成合理坐标的事情（比如(1,-1)变成(0,8)）。
        if(MinesweeperUtilities.isValid(row,col,GameBoardPanel.row,GameBoardPanel.col)) {
            int num = MinesweeperUtilities.codeToNum(row, col, GameBoardPanel.col);
            reveal(num);
        }
    }
    public static void decrease(){
        numOfUnrevealedCells--;
    }
    public void reset(){
        numOfUnrevealedCells=row*col;
        for(Cell[] cell:cells){
            for (Cell cell1:cell){
                cell1.reset();
            }
        }
        MineSweeperMain.setClickable(true);
        SouthMenu.start();
        SouthMenu.setTime(0);
        SouthMenu.setMine(num);
    }

    @Override
    public void mouseClicked(MouseEvent e) {        //鼠标监听器。主要就是单击和双击。
        if(MineSweeperMain.isClickable()) {
            if (e.getButton() == MouseEvent.BUTTON1) {
                if (e.getClickCount() == 1) {
                    if (MineMap.getMineMap().isEmpty()) {
                        MineMap.setMineMap(row, col, num, ((Cell) e.getSource()).getPosition());
                        reveal(((Cell) e.getSource()).getPosition());
                    } else {
                        reveal(((Cell) e.getSource()).getPosition());
                    }
                } else if (e.getClickCount() == 2) {
                    int r = ((Cell) e.getSource()).getRow();
                    int c = ((Cell) e.getSource()).getCol();
                    int flagNumbers = 0;
                    for (int i = r - 1; i <= r + 1; i++) {
                        for (int j = c - 1; j <= c + 1; j++) {
                            if (MinesweeperUtilities.isValid(i, j, row, col) && (i != r || j != c) && cells[i][j].isFlagged() && !cells[i][j].getRevealedStatus()) {
                                flagNumbers++;
                            }
                        }
                    }
                    if (flagNumbers >= cells[r][c].getNumberOfMinesAround()) {
                        for (int i = r - 1; i <= r + 1; i++) {
                            for (int j = c - 1; j <= c + 1; j++) {
                                if (MinesweeperUtilities.isValid(i, j, row, col) && !cells[i][j].getRevealedStatus() && !cells[i][j].isFlagged()) {
                                    reveal(i, j);
                                }
                            }
                        }
                    }

                }
            } else if (e.getButton() == MouseEvent.BUTTON3) {
                ((Cell) e.getSource()).flag();
            }
        }
    }

    @Override
    public void mousePressed(MouseEvent e) {}

    @Override
    public void mouseReleased(MouseEvent e) {}

    @Override
    public void mouseEntered(MouseEvent e) {}

    @Override
    public void mouseExited(MouseEvent e) {}
}
